package com.appbee.songs.client.presenter;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.inject.Inject;

import com.appbee.core.client.jsni.JsArrayConverter;
import com.appbee.core.client.place.EditPlace;
import com.appbee.core.client.place.HasPlace;
import com.appbee.core.client.place.NamedPlace;
import com.appbee.core.client.place.PlaceControl;
import com.appbee.core.client.ui.IMessageView;
import com.appbee.gdata.youtube.client.search.Entry;
import com.appbee.gdata.youtube.client.search.Feed;
import com.appbee.gdata.youtube.client.search.FeedCallback;
import com.appbee.gdata.youtube.client.search.FeedResult;
import com.appbee.gdata.youtube.client.search.YoutubeFilter;
import com.appbee.gdata.youtube.client.search.YoutubeService;
import com.appbee.lyrdb.shared.LyrSongProxy;
import com.appbee.songs.client.SongActivityModul;
import com.appbee.songs.shared.SongProxy;
import com.appbee.songs.shared.SongRequestFactory;
import com.appbee.songs.shared.SongServiceRequest;
import com.appbee.yahoo.query.client.model.Artist;
import com.appbee.yahoo.query.client.model.Track;
import com.appbee.yahoo.query.client.model.TrackList;
import com.appbee.yahoo.query.client.model.TrackResult;
import com.appbee.yahoo.query.client.search.TrackQueryCallback;
import com.appbee.yahoo.query.client.search.YqlMusicService;
import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryEditorDriver;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.RequestFactory;
import com.google.web.bindery.requestfactory.shared.ServerFailure;
import com.google.web.bindery.requestfactory.shared.Violation;

public class SongEditActivity extends AbstractActivity implements HasPlace
{
	public interface View extends IsWidget
	{
		public RequestFactoryEditorDriver<SongProxy, ?> createDriver(EventBus eventBus,RequestFactory rf);
		
		public IMessageView getMessageView();
		
		public void setPresenter(SongEditActivity presenter);
		
		public String getNameValue();

		public void setTrackData(List<Track> list);

		public void showLyricList(List<LyrSongProxy> response);

		public void setLyrics(String response);

		public void addEntry(Entry entry);

		public void clearEntrys();

		public void selectFirstEntry();

		public void clearTubeSearchList();

		public void clearPlayer();

		public void clearTextSearchList();

		public void setNumberValue(Integer value);
	}
	
	private final View view;
	private EditPlace place;
	private final SongRequestFactory songRequestFatory;
	private final PlaceControl placeController;
	private RequestFactoryEditorDriver<SongProxy, ?> driver;
	
	private final Receiver<SongProxy> saveReceiver = new Receiver<SongProxy>()
	{

		@Override
		public void onSuccess(SongProxy response)
		{
			view.getMessageView().showInfo(
SafeHtmlUtils.fromTrustedString("Vistað, id: "
							+ response.getId()));
			SongServiceRequest request = songRequestFatory.getSongService();
			Request<SongProxy> save = request.save(response);
			save.to(saveReceiver);
			driver.edit(response, request);
			
		}

		@Override
		public void onFailure(ServerFailure error)
		{
			view.getMessageView().showError(SafeHtmlUtils.fromString(error.getMessage()));
			super.onFailure(error);
		}

		@Override
		public void onViolation(Set<Violation> errors)
		{
			driver.setViolations(errors);
		}
		
	};
	private final YqlMusicService yqlService;
	private final YoutubeService youtubeService;
	private final SongActivityModul activityModul;
	
	
	@Inject
	public SongEditActivity(View view,
							SongActivityModul activityModul,
 SongRequestFactory serviceProvider,
			PlaceControl placeController,
			YqlMusicService yqlService,
 YoutubeService youtubeService)
	{
		this.view = view;
		this.activityModul = activityModul;
		this.placeController = placeController;
		this.songRequestFatory = serviceProvider;
		this.yqlService = yqlService;
		this.youtubeService = youtubeService;
		view.setPresenter(this);
	}


	@Override
	public void start(final AcceptsOneWidget panel, EventBus eventBus)
	{
		this.driver = view.createDriver(eventBus, songRequestFatory);
		view.getMessageView().clearMessage();
		view.clearTubeSearchList();
		view.clearPlayer();
		view.clearTextSearchList();
		if(place.getId()==null)
		{
			SongServiceRequest request = songRequestFatory.getSongService();
			SongProxy songProxy = request.create(SongProxy.class);
			Request<SongProxy> save = request.save(songProxy);
			save.to(saveReceiver);
			driver.edit(songProxy, request);
			driver.setViolations(new ArrayList<Violation>());
			panel.setWidget(view);
			songRequestFatory.getSongService().getMaxNumber()
					.fire(new Receiver<Integer>()
			{

				@Override
				public void onSuccess(Integer response)
				{
					view.setNumberValue(response + 1);
				}

			});
		}
		else
		{
			Request<SongProxy> findRequest = songRequestFatory.getSongService()
					.findById(place.getId());
			findRequest.fire(new Receiver<SongProxy>()
			{

				@Override
				public void onSuccess(SongProxy response)
				{
					SongServiceRequest request = songRequestFatory
							.getSongService();
					Request<SongProxy> save = request.save(response);
					save.to(saveReceiver);
					driver.edit(response, request);
					driver.setViolations(new ArrayList<Violation>());
					panel.setWidget(view);
				}
				
			});
		}
	}


	@Override
	public void setPlace(Place place)
	{
		this.place = (EditPlace) place;
		
	}


	public void onSave()
	{
		RequestContext context = driver.flush();
		if(!driver.hasErrors())
		{
			context.fire();
		}
		
	}


	public void onCancelClick()
	{
		placeController
				.goTo(new NamedPlace(activityModul.getSongsActivityId()));
		
	}
	
	public void onSearchByTrack()
	{
		String name = view.getNameValue();
		if(name!=null && name.length()>0)
		{
			this.yqlService.findByTrack(name, new TrackQueryCallback()
			{
				
				@Override
				public void onSuccess(TrackResult result)
				{
					TrackList trackList = result.getTrackList();
					GWT.log("count: " + trackList.getCount());
					view.setTrackData(JsArrayConverter.toList(trackList
							.getTracks()));
				}
				
				@Override
				public void onFailure(Throwable caught)
				{
					view.getMessageView().showError(
							SafeHtmlUtils.fromString(caught.getMessage()));
				}
			});
		}
	}
	
	public void onTrackSelected(Track track)
	{
		StringBuffer q = new StringBuffer();
		Artist artist = track.getArtist();
		if(artist!=null)
		{
			q.append(artist.getName());
			q.append(" - ");
		}
		q.append(track.getTitle());
		Request<String> request = songRequestFatory.getLyrDbService()
				.findFirstByFullt(q.toString());
		request.fire(new Receiver<String>()
		{

			@Override
			public void onFailure(ServerFailure error)
			{
				view.getMessageView().showError(SafeHtmlUtils.fromString(error.getMessage()));
			}

			@Override
			public void onSuccess(String response)
			{
				view.setLyrics(response);
			}
			
		});
		YoutubeFilter filter = new YoutubeFilter();
		filter.setMaxResult(6);
		filter.setQuery(q.toString());
		youtubeService.findByFilter(filter, new FeedCallback()
		{
			
			@Override
			public void onSuccess(FeedResult feedResult)
			{
				Feed feed = feedResult.getFeed();
				view.clearEntrys();
				JsArray<Entry> entries = feed.getEntry();
				int n = entries.length();
				for(int i=0;i<n;i++)
				{
					view.addEntry(entries.get(i));
				}
				if(n>0)
				{
					view.selectFirstEntry();
				}
			}
			
			@Override
			public void onFailure(Throwable caught)
			{
				view.getMessageView().showError(
						SafeHtmlUtils.fromString(caught.getMessage()));
			}
		});
	}


	public void onLyricSelection(LyrSongProxy selectedSong)
	{
		songRequestFatory.getLyrDbService().findById(selectedSong.getId())
				.fire(new Receiver<String>()
		{

			@Override
			public void onSuccess(String response)
			{
				view.setLyrics(response);
			}
			
		});
	}

}
